package com.xuanyue.db.xuan.antlr.v2.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;

import org.antlr.v4.runtime.tree.TerminalNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.xuanyue.db.xuan.SeachContextV2;
import com.xuanyue.db.xuan.antlr.v2.BitQV2BaseListener;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.AlertOPContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.AlertTableContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.AndConditionContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.AndNotContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.ArrayIndex0Context;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.ArrayIndex1Context;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.ArrayIndex2Context;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.ArrayIndex3Context;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.ArrayIndexContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.BaseExprContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.BitQContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.CTypeContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.ColumnContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.ConditionElementContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.ConditionExprContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.CreateTableContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.DeleteContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.ExprKeyContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.ExprValueContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.FieldsContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.FunctionContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.GroupConditionContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.InsertIntoContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.LimitContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.OrConditionContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.OrNotContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.QueryContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.RepoContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.ResultContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.SetSourceContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.SetValueContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.SortByContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.SortEContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.To_dateContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.UpdateContext;
import com.xuanyue.db.xuan.antlr.v2.BitQV2Parser.ValuesContext;
import com.xuanyue.db.xuan.core.db.ColumnMetaV2;
import com.xuanyue.db.xuan.core.db.TableMetaV2;
import com.xuanyue.db.xuan.core.exception.SQLException;
import com.xuanyue.db.xuan.core.table.IXyTable;
import com.xuanyue.db.xuan.core.table.expr.Expr;
import com.xuanyue.db.xuan.core.table.expr.ExprValue;
import com.xuanyue.db.xuan.core.table.expr.ExprValueType;
import com.xuanyue.db.xuan.core.table.expr.Function;
import com.xuanyue.db.xuan.core.table.expr.IExprKey;
import com.xuanyue.db.xuan.core.table.expr.LimitInfo;
import com.xuanyue.db.xuan.core.table.expr.Settor;
import com.xuanyue.db.xuan.core.table.expr.SortTemplate;

/**
 * sql 解析基本流程
 *
 * @author 解观海
 * @email guanhaixie@sina.cn
 * @date 2020年12月27日
 *
 */
public abstract class AbstractBitQV2Listener extends BitQV2BaseListener {
	private static Logger log = LoggerFactory.getLogger(AbstractBitQV2Listener.class);
	/** 数据表 */
	protected IXyTable table;
	/**结果列*/
	protected Set<String> fields = new HashSet<>();
	
	protected ExprValue parameters;
	///////////////////////////////////////////////////////////////////////////
	//////////////////////////  Transfer parameters ///////////////////////////////////////
	public void setParameters(ExprValue parameters ) {
		this.parameters=parameters;
	}
	
	protected boolean hasParameter() {
		return this.parameters!=null;
	}
	protected boolean isBatch() {
		if(!hasParameter()) {
			return false;
		}
		if(!ExprValueType.MAP.is(this.parameters.getType())) {//;
			throw new SQLException("传递参数时parameters必须为  ExprValueType.MAP类型");
		}
		Map<String,ExprValue> info = this.parameters.getValue();
		if(!info.containsKey("isBatch")) {//;
			throw new SQLException("parameters中必须包含   key值:\"isBatch\"");
		}
		if(!ExprValueType.BOOLEAN.is(info.get("isBatch").getType())) {
			throw new SQLException("参数格式错误 at isBatch");
		}
		boolean isBatch = info.get("isBatch").getValue();
		if(!isBatch) {
			return false;
		}
		if(info.get("values")==null) {
			throw new SQLException("参数错误 , values is null");
		}
		
		if(!ExprValueType.ARRAY.is( info.get("values").getType())) {
			throw new SQLException("参数格式错误  values is not a array");
		}
		List<ExprValue> ps = info.get("values").getValue();
		
		for(ExprValue p:ps) {
			if(!ExprValueType.MAP.is( p.getType() )) {
				throw new SQLException("参数错误 , avery one of values mast be ExprValueType.MAP");
			}
		}
		
		return info.get("isBatch").getValue();
	}
	private boolean isSingle() {
		if(!hasParameter()) {
			return false;
		}
		if(!ExprValueType.MAP.is(this.parameters.getType())) {//;
			throw new SQLException("传递参数时parameters必须为  ExprValueType.MAP类型");
		}
		Map<String,ExprValue> info = this.parameters.getValue();
		if(!info.containsKey("isBatch")) {//;
			throw new SQLException("parameters中必须包含   key值:\"isBatch\"");
		}
		if(!ExprValueType.BOOLEAN.is(info.get("isBatch").getType())) {
			throw new SQLException("参数格式错误 at isBatch");
		}
		boolean isBatch = info.get("isBatch").getValue();
		if(isBatch) {
			return false;
		}
		if(info.get("values")==null) {
			throw new SQLException("参数错误 , values is null");
		}
		if(!ExprValueType.MAP.is( info.get("values").getType())) {
			throw new SQLException("Single 参数格式错误  values mast be MAP");
		}
		return true;
	}
	protected ExprValue getSingleParameter() {
		if(!isSingle()) {
			throw new SQLException("参数不是Single理模式");
		}
		Map<String,ExprValue> info = this.parameters.getValue();
		return info.get("values");
	}
	protected List<ExprValue> getBatchParameter(){
		if(!isBatch()) {
			throw new SQLException("参数不是批处理模式");
		}
		Map<String,ExprValue> info = this.parameters.getValue();
		return info.get("values").getValue();
	}
	
	//////////////////////////Transfer parameters ///////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////
	//////////////////////////   meta lock ///////////////////////////////////////
	protected abstract ReadLock getReadLockOfMeta();
	protected abstract WriteLock getWriteLockOfMeta();
	
	//////////////////////////meta lock ///////////////////////////////////////
	//////////////////////////////////////////////////////////////////////
	///////////////////////////逻辑表达///////////////////////////////////////
	protected abstract void exeVersionRemember();
	protected abstract void exePP();
	protected abstract void exeReduce();
	
	/**
	 * 和当前结果or 合并
	 * @param offset
	 * @author 解观海
	 * @date 2020年12月28日
	 */
	protected abstract void exeOr(int offset);
	/**
	 * 和当前结果and 合并
	 * @param offset
	 * @author 解观海
	 * @date 2020年12月28日
	 */
	protected abstract void exeAnd(int offset);
	/**
	 * 当前计算结果重置
	 * @param value
	 * @author 解观海
	 * @date 2020年12月28日
	 */
	protected abstract void exeSetAll(boolean value);
	/**
	 * 复制mask
	 * 
	 * @author 解观海
	 * @date 2020年12月29日
	 */
	protected abstract void exeCopyMask();
	/**
	 * 
	 * @param value
	 * @author 解观海
	 * @date 2020年12月28日
	 */
	protected abstract void exeAndMask();
	/**
	 * 申请资源
	 * 
	 * @author 解观海
	 * @date 2020年12月28日
	 */
	protected abstract void exeApplySrouce();
	/**
	 * 释放资源
	 * 
	 * @author 解观海
	 * @date 2020年12月28日
	 */
	protected abstract void exeReturnSrouce();
	
	/**
	 * 处理表达式中 的 not 关键字
	 * @param notIsNull
	 * @author 解观海
	 * @date 2020年12月24日
	 */
	protected abstract void handle(boolean notIsNull);
	/**
	 * 字符串 参数 剔除头和尾
	 * @param text
	 * @return
	 * @author 解观海
	 * @date 2020年12月26日
	 */
	private  String valueOfStr(String text) {
		return text.substring(1, text.length()-1);
	}
	/**日期格式化为 Date对象
	 * 
	 * @param toDate
	 * @return
	 * @author 解观海
	 * @date 2020年12月26日
	 */
	private Date toDate(To_dateContext toDate) {
		
		try {
			String fmt = valueOfStr(toDate.STRING(0).getText());
			String v = valueOfStr(toDate.STRING(1).getText());
			
			SimpleDateFormat formatter = new SimpleDateFormat(fmt);
			return formatter.parse(v);
		} catch (Exception e) {
			throw new SQLException("error at:"+toDate.toString());
		}
	}
	/** 数值类型参数转 数值对象 */
	private Number num(String txt,ExprValue r) {
		if(txt.endsWith("l")) {
			r.setType(ExprValueType.LONG);
			long x = Long.parseLong( txt.substring(0,txt.length()-1)  );
			r.setValue( x );
			return x;
		}else if(txt.endsWith("f")) {
			r.setType(ExprValueType.FLOAT);
			float x = Float.parseFloat(txt.substring(0,txt.length()-1)) ;
			r.setValue( x);
			return x;
		}else {
			r.setType(ExprValueType.INT);
			int x = Integer.parseInt(txt);
			r.setValue(x );
			return x;
		}
	}
	private Number num(String txt) {
		if(txt.endsWith("l")) {
			return Long.parseLong( txt.substring(0,txt.length()-1)  );
		}else if(txt.endsWith("f")) {
			return Float.parseFloat(txt.substring(0,txt.length()-1));
		}else {
			return Integer.parseInt(txt);
		}

	}
	/**
	 * 基本数据类型转数据对象
	 * @param val
	 * @return
	 * @author 解观海
	 * @date 2020年12月26日
	 */
	private ExprValue transferToExprValue(ValuesContext val) {
		ExprValue r = new ExprValue();
		if(val.to_date()!=null) {
			r.setType(ExprValueType.DATE);
			r.setValue( toDate(val.to_date()) );
		}else if(val.STRING()!=null) {
			r.setType(ExprValueType.STRING);
			r.setValue( valueOfStr( val.STRING().getText()  ) );
		}else if(val.NUM()!=null) {
			num(val.NUM().getText(),r); 
		}else if(val.boolTF()!=null) {
			r.setType(ExprValueType.BOOLEAN);
			r.setValue( (val.boolTF().FALSE()==null) );
		}else if(val.TransArrt()!=null) {
			r.setType(ExprValueType.TRANSATTR);
			String key = val.TransArrt().getText().toLowerCase();
			r.setValue( key.substring(1, key.length()) );
		}else if(val.NULL()!=null) {
			r.setType(ExprValueType.NULL);
			r.setValue(null);
		}else {
			throw new SQLException("the type is not support:"+val.toString());
		}
		return r;
	}
	/**
	 * 逻辑表达式右侧值转数据对象
	 * @param value
	 * @return
	 * @author 解观海
	 * @date 2020年12月26日
	 */
	private ExprValue getValue(ExprValueContext value) {
		ExprValue r = null;//new ExprValue();
		
		if(value.values()!=null) {
			r= transferToExprValue(value.values());
		}else if(value.array()!=null) {
			r = new ExprValue();
			List<ExprValue> list = new ArrayList<>();
			List<ValuesContext> vs = value.array().values();
			for(ValuesContext v:vs) {
				list.add( transferToExprValue(v)  );
			}
			r.setType(ExprValueType.ARRAY);
			r.setValue(list);
		}
		return r;
	}
	/**
	 * 逻辑表示左侧
	 * @param key
	 * @param expr
	 * @author 解观海
	 * @date 2020年12月26日
	 */
	private void handle(ExprKeyContext key,IExprKey expr) {
		
		/**
		 * 无冒号时  0   表示数组索引
		 * 
		 * 有冒号时有如下4种情况：         
		 *          后面有     后面无
		 *    前面有         1     2
		 *    前面无         3     4
		 * 
		 * 
		 */
		ArrayIndexContext aic = key.arrayIndex();
		if(aic!=null) {
			if(aic.arrayIndex0()!=null) {
				ArrayIndex0Context ai0 = aic.arrayIndex0();
				expr.setArryIndex(new int[] {num(ai0.NUM().getText()).intValue(),0,0});
			}else if(aic.arrayIndex1()!=null) {
				ArrayIndex1Context ai1 = aic.arrayIndex1();
				expr.setArryIndex(new int[] {
						num(ai1.NUM(0).getText()).intValue(),
						1,
						num(ai1.NUM(1).getText()).intValue(),
				});
			}else if(aic.arrayIndex2()!=null) {
				ArrayIndex2Context ai2 = aic.arrayIndex2();
				expr.setArryIndex(new int[] {
						num(ai2.NUM().getText()).intValue(),
						2,
						0,
				});
			}else if(aic.arrayIndex3()!=null) {
				ArrayIndex3Context ai3 = aic.arrayIndex3();
				expr.setArryIndex(new int[] {
						0,
						3,
						num(ai3.NUM().getText()).intValue(),
				});
			}else if(aic.arrayIndex4()!=null){
				//退化为 无索引
				expr.setArryIndex(null);
			}else {
				throw new SQLException("arrayIndex mode is not support");
			}
		}
		
		TerminalNode k = key.STRING();
		if(k!=null) {
			expr.setKey(valueOfStr(k.getText()));
		}
	}
	/**
	 * 基本逻辑表达式转成对象
	 * 
	 * values:包含
	 * 基本类型  
	 * DATE,日期
	 * STRING,字符串
	 * NUMBER,数组
	 * TRANSATTR,传递参数    ?参数名
	 * NULL, 空
	 * BOOLEAN, 真值
	 * 
	 * 数组类型  
	 * ARRAY  基本类型的数组
	 * 
	 * 1、  列名     [= != >  >= <  <=]  values
	 * 2、 Map类型的列名['key']  [= != >  >= <  <=]  values
	 * 3、List类型的列名[index]  [= != >  >= <  <=]  values 
	 *    index 的语法模仿python的数组索引
	 *    a=[1,2,3,4,5]
	 *    a[0]=1
	 *    a[1:5]=[2,3,4,5]
	 *    a[0:-1]=[1,2,3,4]
	 * @param base
	 * @author 解观海
	 * @date 2020年12月26日
	 */
	protected Expr handle(BaseExprContext base) {
		Expr expr = new Expr();
		/**1、列名*/
		String cname = base.NAME().getText().toLowerCase();
		if(table.getColumn(cname)==null) {
			throw new SQLException("the column is not exists: "+cname);
		}
		expr.setCname(cname);
		/**2、数组的索引或map的key值*/
		if(base.exprKey()!=null) {
			handle(base.exprKey(),expr);
		}
		expr.setOp(base.op.getText());
		expr.setValue(getValue(base.exprValue()));
		return expr;
	}
	/**
	 * 自定义函数    function( 列名,函数名, 参数  ...  );
	 * @param fc
	 * @author 解观海
	 * @date 2020年12月26日
	 */
	private Function handle(FunctionContext fc) {
		List<TerminalNode> names = fc.NAME();
		String cname = names.get(0).getText().toLowerCase();
		if(table.getColumn(cname)==null) {
			throw new SQLException("the column is not exists: "+cname);
		}
		Function function = new Function();
		
		ExprKeyContext ek = fc.exprKey();
		if(ek!=null) {
			handle(ek,function);
		}
		String fname = names.get(1).getText().toLowerCase();
		function.setCname(cname);
		function.setFunctionName(fname);
		List<ExprValue> list = new ArrayList<>();
		List<ValuesContext> vs = fc.values();
		for(ValuesContext v:vs) {
			list.add( transferToExprValue(v)  );
		}
		function.setValues(list);
		return function;
	}
	/**
	 * 逻辑表达式最终执行
	 * @param expr
	 * @author 解观海
	 * @date 2020年12月26日
	 */
	protected abstract int handle(Expr expr);
	/**
	 * 自定义逻辑函数的执行
	 * @param function
	 * @author 解观海
	 * @date 2020年12月26日
	 */
	protected abstract int handle(Function function);
	/**
	 * 处理逻辑表达式
	 * 包含两类：
	 * 1  基本类型
	 * 2、自定义函数
	 *  
	 * @param expr
	 * @author 解观海
	 * @date 2020年12月26日
	 */
	protected void handle(ConditionExprContext expr) {
		if(expr.baseExpr()!=null) {
			if(handle(handle(expr.baseExpr()))==0) {//基本类型
				throw new SQLException("error at:"+expr.getText());
			}
		}else if(expr.function()!=null) {
			if(handle(handle(expr.function()))==0) {//自定义函数
				throw new SQLException("error at:"+expr.getText());
			}
		}else {
			throw new SQLException("expr error:"+expr.toString());
		}
	}
	/**
	 * 逻辑表达式的 括号   :  (   )
	 * @param group
	 * @author 解观海
	 * @date 2020年12月26日
	 */
	protected void handle(GroupConditionContext group) {
		handle(group.orCondition());
	}
	/**
	 * 逻辑表达式 单元处理
	 * @param ele
	 * @author 解观海
	 * @date 2020年12月26日
	 */
	protected void handle(ConditionElementContext ele) {
		if(ele.groupCondition()!=null) {
			handle(ele.groupCondition());
		}else if(ele.conditionExpr()!=null) {
			handle(ele.conditionExpr());
		}else {
			throw new SQLException( "error at : "+ele.toString() );
		}
	}
	/**
	 * and 逻辑表达式
	 * @param andCondition
	 * @author 解观海
	 * @date 2020年12月26日
	 */
	protected void handle(AndConditionContext andCondition) {
		List<ConditionElementContext> eles = andCondition.conditionElement();
		List<AndNotContext> andNots = andCondition.andNot();
		List<Boolean> tf = new ArrayList<>();
		tf.add(true);
		
		for(AndNotContext andNot:andNots) {
			tf.add( andNot.NOT()==null );
		}
		exeSetAll(true);
		for(int i=0,s=eles.size();i<s;i++) {
			exePP();
			handle(eles.get(i));
			handle(tf.get(i));
			exeReduce();
			exeAnd(1);
		}
	}
	
	/**
	 * or 逻辑表达式
	 * @param or
	 * @author 解观海
	 * @date 2020年12月26日
	 */
	protected void handle(OrConditionContext or) {
		List<AndConditionContext>  andList = or.andCondition();
		List<OrNotContext> orNots = or.orNot();
		List<Boolean> tf = new ArrayList<>();
		tf.add(or.NOT()==null ) ;
		for(OrNotContext orNot:orNots) {
			tf.add( orNot.NOT()==null);
		}
		exeSetAll(false);
		for(int i=0,s=andList.size();i<s;i++) {
			exePP();
			handle(andList.get(i));
			handle(tf.get(i));
			exeReduce();
			exeOr(1);
		}
	}
	
	/////////////////////////////逻辑表达/////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////
	/////////////////////////  sort by  ////////////////////////////////////
	
	/**
	 * 排序模板
	 * @param sortEContext
	 * @return
	 * @author 解观海
	 * @date 2020年12月26日
	 */
	private SortTemplate handle(SortEContext sortEContext) {
		SortTemplate t = new SortTemplate();
		t.setCname( sortEContext.NAME().getText().toLowerCase() );
		if(sortEContext.exprKey()!=null) {
			handle( sortEContext.exprKey() ,t );
		}
		t.setDesc(sortEContext.ASC()==null);
		return t;
	}
	/**
	 * 处理排序
	 * @param sortBy
	 * @author 解观海
	 * @date 2020年12月26日
	 */
	private List<SortTemplate> handle(SortByContext sortBy) {
		List<SortEContext>  sortEList = sortBy.sortE();
		List<SortTemplate> sl = new ArrayList<>();
		for(SortEContext e:sortEList) {
			sl.add( handle(e) );
		}
		return sl;
	}
	/**
	 * 排序 和 分页
	 * 如果自然顺序 sortTemplateList为null
	 * @param sortTemplateList
	 * @author 解观海
	 * @date 2020年12月26日
	 */
	protected abstract void handle(List<SortTemplate> sortTemplateList,LimitInfo limitInfo);
	
	
	/////////////////////////  sort by ////    end    ////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////
	//////////////////////////  update  //////   start   //////////////////////////////////////
	protected abstract void exeUpdate(List<Settor> settors );
	//////////////////////////  update  //////   end    ////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////
	//////////////////////////  delete  //////   start  /////////////////////////////////
	protected abstract void exeDelete();
	/////////////////////////   delete  /////   end    ////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////
	/////////////////////////  insert into //// start   //////////////////////////////////
	protected abstract void exeInsertInto(Map<String,ExprValue> c2Value);
	/////////////////////////  insert into ////  end   //////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////
	////////////////////////// create table ///  start //////////////////////////////
	
	private Map<String,Object> handle(CTypeContext ct) {
		Map<String,Object> r = new HashMap<>();
		if(null!=ct.intType()) {//int   1
			r.put("typeName", "IntIndex");
			r.put("max", num(ct.intType().NUM().getText()).intValue());
			return r;
		}else if(null!=ct.uintType()) {//u int 2
			r.put("typeName", "UIntIndex");
			r.put("max", num(ct.uintType().NUM().getText()).intValue());
			return r;
		}else if(null!=ct.longType()) {//long  3
			List<TerminalNode> nums = ct.longType().NUM();
			r.put("typeName", "LongIndex");
			r.put("size", num(nums.get(0).getText()).intValue());
			if(nums.size()==2) {
				r.put("zero", num(nums.get(1).getText()).longValue());
			}
			return r;
		}else if(null!=ct.ulongType()) {//u long 4
			r.put("typeName", "ULongIndex");
			r.put("max", num(ct.intType().NUM().getText()).intValue());
			return r;
		}else if(null!=ct.floatType()) {// float 5
			List<TerminalNode> nums = ct.floatType().NUM();
			r.put("typeName", "FLOATIndex");//int size,int eNum,int zero
			r.put("size", num(nums.get(0).getText()).intValue());
			r.put("eNum", num(nums.get(1).getText()).intValue());
			if(nums.size()==3) {
				r.put("zero", num(nums.get(2).getText()).longValue());
			}
			return r;
		}else if(null!=ct.ufloatType()) {//u float 6
			r.put("typeName", "UFLOATIndex");
			List<TerminalNode> nums = ct.ufloatType().NUM();
			r.put("size", num(nums.get(0).getText()).intValue());
			r.put("eNum", num(nums.get(1).getText()).intValue());
			return r;
		}else if(null!=ct.dateType()) {// date 7
			r.put("typeName", "DateIndex");
			return r;
		}else if(null!=ct.booleanType()) {// boolean 8
			r.put("typeName", "BooleanIndex");
			return r;
		}else if(null!=ct.listType()) {// list 9
			CTypeContext ctl = ct.listType().cType();
			r.put("typeName", "ListObject");
			r.put("eleType", handle(ctl));
			r.put("num", num(ct.listType().NUM().getText()).intValue());
			return r;
		}else if(null!=ct.mapType()) {//map 10
			CTypeContext ctl = ct.mapType().cType();
			r.put("typeName", "MapIndex");
			r.put("eleType", handle(ctl));
			List<String> keys = new ArrayList<>();
			List<TerminalNode> names = ct.mapType().NAME();
			for(TerminalNode name:names) {
				keys.add( name.getText().toLowerCase() );
			}
			r.put("keys", keys);
			return r;
		}else if(null!=ct.phoneType()) {
			r.put("typeName", "PhoneIndex");
			return r;
		}else {
			return null;
		}
	}
	
	
	protected abstract void exeCreateTable(TableMetaV2 tableMetaV2);
	
	/////////////////////////  create table /// end ///////////////////////
	////////////////////////////////////////////////////////////////////////////////
	///////////////////////////  alert /// start //////////////////////
	
	private void handle(AlertOPContext op) {
		if(op.ADD()!=null) {
			ColumnContext column = op.column();
			ColumnMetaV2 cmV2 = new ColumnMetaV2();
			String cname = column.NAME().getText().toLowerCase();
			cmV2.setName(cname);
			if(table.getColumn(cname)!=null) {
				throw new SQLException(String.format("column %s has existed", cname));
			}
			cmV2.setType(handle( column.cType()));
			exeAddColumn(cmV2);
		}else if(op.DROP()!=null) {
			String cname = op.NAME().getText().toLowerCase();
			if(table.getColumn(cname)==null) {
				throw new SQLException(String.format("column %s is not exists", cname));
			}
			exeDropColumn(cname);
		}else if(op.ALTER()!=null) {
			String cname = op.NAME().getText().toLowerCase();
			ColumnContext column = op.column();
			ColumnMetaV2 cmV2 = new ColumnMetaV2();
			cmV2.setName(column.NAME().getText().toLowerCase());
			cmV2.setType(handle( column.cType()));
			exeAlertColumn(cname,cmV2);
		}else if(op.setSource()!=null) {
			exeSetSource(num(op.setSource().NUM().getText()).intValue());
		}else {
			throw new SQLException(String.format("alert error:%s", op.toString()));
		}
	}
	protected abstract void exeSetSource(int source);
	protected abstract void exeDropColumn(String cname);
	protected abstract void exeAddColumn(ColumnMetaV2 cmV2);
	protected abstract void exeAlertColumn(String oldName,ColumnMetaV2 cmV2);
	
	//////////////////////////////// alert ////  end  //////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////
	/**
	 * 插入
	 * @param inser
	 * @author 解观海
	 * @date 2020年12月27日
	 */
	protected void handle(InsertIntoContext inser) {
		String tn = inser.NAME().getText().toLowerCase();
		table = SeachContextV2.getTable(tn);
		if(table==null) {//表不存在
			throw new SQLException(String.format("table %s is not exists", tn));
		}
		
		FieldsContext fsc = inser.fields();
		List<TerminalNode> names = fsc.NAME();
		List<ExprValueContext> evl = inser.exprValue();
		
		if(names.size()!=evl.size()) {
			throw new SQLException(String.format("the size(%s) of fieldName List is not equeals to the size(%s) of values", names.size(),evl.size()));
		}
		
		Map<String,ExprValue> c2Value = new HashMap<>();
		for(int i=0,s=names.size();i<s;i++) {
			c2Value.put(names.get(i).getText().toLowerCase(), getValue(evl.get(i)));
		}
		exeInsertInto(c2Value);
	}
	/**
	 * 修改表模型
	 * @param alertTable
	 * @author 解观海
	 * @date 2020年12月27日
	 */
	protected void handle(AlertTableContext alertTable) {
		String tableName = alertTable.NAME().getText().toLowerCase();
		table = SeachContextV2.getTable(tableName);
		if(table==null) {//表不存在
			throw new SQLException(String.format("table %s is not exists", tableName));
		}
		handle(alertTable.alertOP());
	}
	/**
	 * 创建表
	 * @param createTable
	 * @author 解观海
	 * @date 2020年12月27日
	 */
	protected void handle(CreateTableContext createTable) {
		String tn = createTable.NAME().getText().toLowerCase();
		TableMetaV2 tm = new TableMetaV2();
		tm.setName(tn);
		
		List<ColumnContext> cs = createTable.column();
		ColumnMetaV2 cmV2 = null;
		for(ColumnContext cc:cs) {
			cmV2 = new ColumnMetaV2();
			cmV2.setType( handle(cc.cType()) );
			cmV2.setName( cc.NAME().getText().toLowerCase() );
			tm.add(cmV2);
		}
		SetSourceContext source = createTable.setSource();
		if(source!=null) {
			tm.setSource(num(source.NUM().getText().toLowerCase()).intValue() );
		}else {
			tm.setSource(80);
		}
		exeCreateTable(tm);
	}
	/**
	 * 查询语句
	 * @param query
	 * @author 解观海
	 * @date 2020年12月26日
	 */
	protected void handle(QueryContext query) {
		/**
		 * 1 from 表
		 */
		RepoContext repo = query.repo();
		if(repo==null) {//无from
			throw new SQLException("error at from");
		}
		TerminalNode name = repo.NAME();
		if(name==null) {//表名空
			throw new SQLException("error at from");
		}
		String tn = name.getText().toLowerCase();
		table = SeachContextV2.getTable(tn);
		if(table==null) {//表不存在
			throw new SQLException(String.format("table %s is not exists", tn));
		}
		//2 结果列表
		ResultContext result = query.result();
		if(result==null||result.NAME()==null||result.NAME().size()==0) {
			throw new SQLException("error at select");//查询的结果字段名为空
		}
		String fn = null;
		for(TerminalNode node:result.NAME()) {
			fn = node.getText();
			if(null==table.getColumn(fn)) {//查询的结果字段不存在
				throw new SQLException(String.format("the field name error at %s ", fn));
			}
			fields.add(fn);
		}
		try {
			exeVersionRemember();//获得当前数据版本
			exeApplySrouce();//申请资源
			
			
			//3 where 条件
			if(query.orCondition()!=null) {
				handle(query.orCondition());
			}else {//无 where 
				exeSetAll(true);
			}
			exeAndMask();
			
			//4 limit 
			LimitInfo limitInfo = new LimitInfo();
			LimitContext limit = query.limit();
			if(limit!=null) {
				List<TerminalNode> nums = limit.NUM();
				if(nums.size()==2) {
					limitInfo.setOffset( num(nums.get(0).getText()).intValue()  );
					limitInfo.setNum( num(nums.get(1).getText()).intValue()  );
				}else {
					limitInfo.setOffset(0);
					limitInfo.setNum( num(nums.get(0).getText()).intValue()  );
				}
			}else {
				limitInfo.setOffset(0);
				limitInfo.setNum(1000);
			}
			//4 sortBy
			List<SortTemplate> sortTemplateList = null;//handle(query.sortBy());
			if(query.sortBy()!=null) {
				sortTemplateList = handle(query.sortBy());
			}
			handle(sortTemplateList,limitInfo);
		}catch (SQLException e) {
			log.error("error:",e);
			throw e; 
		}finally {
			exeReturnSrouce();//释放资源
		}
		
	}
	/**
	 * update语句
	 * @param update
	 * @author 解观海
	 * @date 2020年12月26日
	 */
	protected void handle(UpdateContext update) {
		
		String tn = update.NAME().getText().toLowerCase();
		table = SeachContextV2.getTable(tn);
		if(table==null) {//表不存在
			throw new SQLException(String.format("table %s is not exists", tn));
		}
		List<SetValueContext> setterContexts = update.setValue();
		List<Settor> settors = new ArrayList<>();
		Settor settor = null;
		for(SetValueContext sv:setterContexts) {
			settor = new Settor();
			settor.setCname(sv.NAME().getText().toLowerCase());
			settor.setExprValue(transferToExprValue(sv.values()));
			settors.add(settor);
			if(table.getColumn(settor.getCname())==null) {
				throw new SQLException(String.format("the column %s is not exists", settor.getCname()));
			}
		}
		try {
			exeVersionRemember();
			exeApplySrouce();//申请资源
			if(update.orCondition()!=null) {
				handle(update.orCondition());
			}else {//无 where 
				exeSetAll(true);
			}
			exeAndMask();
			
			exeUpdate(settors);
		} finally {
			exeReturnSrouce();//申请资源
		}
		
	}
	/**
	 * delete语句
	 * @param delete
	 * @author 解观海
	 * @date 2020年12月26日
	 */
	protected void handle(DeleteContext delete) {
		String tn = delete.NAME().getText().toLowerCase();
		table = SeachContextV2.getTable(tn);
		if(table==null) {//表不存在
			throw new SQLException(String.format("table %s is not exists", tn));
		}
		exeVersionRemember();//获得当前数据版本
		try {
			exeApplySrouce();//申请资源
			if(delete.orCondition()!=null) {
				handle(delete.orCondition());
			}else {//无 where 
				exeSetAll(true);
			}
			exeAndMask();
			exeDelete();
		} finally {
			exeReturnSrouce();//申请资源
		}
	}
	/**
	 * 所有sql的入口
	 */
	@Override
	public void exitBitQ(BitQContext ctx) {
		ReadLock read=null;
		try {
			if(ctx.insertInto()!=null) {
				read= getReadLockOfMeta();
				if(read!=null)
					read.lock();
				handle(ctx.insertInto());
			}else if(ctx.query()!=null) {
				read= getReadLockOfMeta();
				if(read!=null)
					read.lock();
				handle(ctx.query());
			}else if(ctx.update()!=null) {
				read= getReadLockOfMeta();
				if(read!=null)
					read.lock();
				handle(ctx.update());
			}else if(ctx.delete()!=null) {
				read= getReadLockOfMeta();
				if(read!=null)
					read.lock();
				handle(ctx.delete());
			}
		}finally {
			if(read!=null) {
				read.unlock();
				return;
			}
		}
		WriteLock write = null;
		try {
			
			if(ctx.alertTable()!=null) {
				write = getWriteLockOfMeta();
				if(write!=null)
					write.lock();
				handle(ctx.alertTable());
			}
			if(ctx.createTable()!=null) {
				write = getWriteLockOfMeta();
				if(write!=null)
					write.lock();
				handle(ctx.createTable());
			}
		}finally {
			if(write!=null) {
				write.unlock();
			}
		}
	}
}
